<!--
 * @Descripttion: 表格选择器组件
 * @version: 1.3
 * @Author: sakuya
 * @Date: 2021年6月10日10:04:07
 * @LastEditors: sakuya
 * @LastEditTime: 2022年6月6日21:50:36
-->

<template>
	<el-select popper-class="ta-cascader-popper" ref="select" v-model="defaultValue" :size="size" :clearable="clearable"
		:multiple="multiple" :max-collapse-tags="3" :collapse-tags="collapseTags"
		:collapse-tags-tooltip="collapseTagsTooltip" :filterable="filterable" :placeholder="placeholder"
		:disabled="disabled" :filter-method="filterMethod" @remove-tag="removeTag" @visible-change="visibleChange"
		@clear="clear">
		<template #empty>
			<div class="sc-table-select__table" :style="{width: 'fit-content'}" v-loading="loading">
				<el-cascader-panel v-show="!filtering" ref="cascaderPanelRef" :props="props" v-model="panelModel"
					style="width: fit-content" :options="tableData" />
				<el-scrollbar v-if="filterable" v-show="filtering" ref="suggestionPanel" tag="ul">
					<template v-if="suggestions.length">
						<li :key="item.uid" :tabindex="-1" class="el-cascader__suggestion-item"
							:class="[item.checked?'is-checked':'']" v-for="item in suggestions"
							@click="handleSuggestionClick(item)">
							<slot name="suggestion-item" :item="item">
								<span>{{ item.text }}</span>
								<el-icon v-if="item.checked">
									<check />
								</el-icon>
							</slot>
						</li>
					</template>
				</el-scrollbar>

			</div>
		</template>
	</el-select>
</template>

<script>
	import config from "@/config/tableSelect";

	export default {
		props: {
			modelValue: null,
			apiObj: {
				type: Object,
				default: () => {}
			},
			params: {
				type: Object,
				default: () => {}
			},
			placeholder: {
				type: String,
				default: "请选择"
			},
			size: {
				type: String,
				default: "default"
			},
			clearable: {
				type: Boolean,
				default: true
			},
			multiple: {
				type: Boolean,
				default: true
			},
			filterable: {
				type: Boolean,
				default: true
			},
			collapseTags: {
				type: Boolean,
				default: true
			},
			collapseTagsTooltip: {
				type: Boolean,
				default: true
			},
			disabled: {
				type: Boolean,
				default: false
			},
			tableWidth: {
				type: Number,
				default: 400
			},
			mode: {
				type: String,
				default: "popover"
			},
			props: {
				type: Object,
				default: () => {
					return {
						value: 'id',
						label: 'label',
						leaf: 'isLeaf',
						multiple: true,
						emitPath: false,
						disabled: (data, node) => {
							return false;
							// this.params.filter[0].value == node.level;
						}
					};
				}
			}
		},
		data() {
			return {
				filtering: false,
				suggestions: [],
				panelModel: null,
				loading: false,
				keyword: null,
				defaultValue: [],
				tableData: [],
				defaultProps: {
					label: config.props.label,
					value: config.props.value,
					page: config.request.page,
					keyword: config.request.keyword
				},
				formData: {}
			}
		},
		computed: {

		},
		watch: {
			modelValue: {
				handler() {
					this.defaultValue = this.modelValue
					this.autoCurrentLabel()
				},
				deep: true
			},
			panelModel: {
				handler(newValue) {
					var data = [];
					const parentMap = {};

					this.forNode(this.tableData, (node) => {
						// 建立子节点到父节点的映射
						if (node.children) {
							node.children.forEach(child => {
								parentMap[child.id] = node;
							});
						}

						if (newValue.includes(node.id)) {
							// 构建路径
							const pathLabels = [];
							let current = node;
							while (current) {
								pathLabels.unshift(current.label); // 将父节点的label依次插入数组头部
								current = parentMap[current.id]; // 获取父节点
							}
							// 将路径拼接成字符串，如 "父节点/当前节点"
							const path = pathLabels.join('/');

							data.push({
								id: node.id,
								label: path,
								name: node.name,
								path: path // 添加路径属性
							});
						}
					});

					this.defaultValue = data;
					this.autoCurrentLabel()
					this.$emit('update:modelValue', this.defaultValue);
				},
				deep: true
			}
		},
		mounted() {
			this.defaultProps = Object.assign(this.defaultProps, this.props);
			this.defaultValue = this.modelValue
			this.autoCurrentLabel()
		},
		methods: {
			forNode(node, callback) {
				// 检查 node 是否为数组
				if (Array.isArray(node)) {
					// 如果传入的是数组，递归遍历每个元素
					node.forEach(child => this.forNode(child, callback));
				} else {
					// 处理单个节点
					callback(node);
					// 如果有 children 则继续递归
					if (node.children) {
						node.children.forEach(child => this.forNode(child, callback));
					}
				}
			},
			//表格显示隐藏回调
			visibleChange(visible) {
				if (visible) {
					this.keyword = null
					this.formData = {}
					this.getData()
				} else {
					this.autoCurrentLabel()
				}
			},
			//获取表格数据
			async getData() {
				if (this.tableData.length > 0) {
					return;
				}
				this.loading = true;
				var reqData = {
					[this.defaultProps.keyword]: this.keyword
				}
				Object.assign(reqData, this.params, this.formData)
				var res = await this.apiObj.get(reqData);
				var parseData = config.parseData(res)
				this.tableData = parseData.rows ? parseData.rows : parseData.data;
				this.loading = false;
				//表格默认赋值
				this.$nextTick(() => {
					if (this.multiple) {
						this.panelModel = this.defaultValue.map(item => item.id)

					} else {
						//var setrow = this.tableData.filter(item => item[this.defaultProps.value] === this
						//.defaultValue[this.defaultProps.value])
						//this.$refs.table.setCurrentRow(setrow[0]);
					}
					//this.$refs.table.setScrollTop(0)
				})
			},
			//插糟表单提交
			formSubmit() {
				this.keyword = null
				this.getData()
			},
			//分页刷新表格
			reload() {
				this.getData()
			},
			//自动模拟options赋值
			autoCurrentLabel() {
				this.$nextTick(() => {
					if (this.multiple) {
						this.$refs.select.states.selected.forEach(item => {
							item.currentLabel = item.value[this.defaultProps.label]
						})
					} else {
						this.$refs.select.states.selectedLabel = this.defaultValue[this.defaultProps.label]
					}
				})
			},
			//表格勾选事件
			select(rows, row) {
				var isSelect = rows.length && rows.indexOf(row) !== -1
				if (isSelect) {
					this.defaultValue.push(row)
				} else {
					this.defaultValue.splice(this.defaultValue.findIndex(item => item[this.defaultProps.value] == row[this
						.defaultProps.value]), 1)
				}
				this.autoCurrentLabel()
				this.$emit('update:modelValue', this.defaultValue);
				this.$emit('change', this.defaultValue);
			},
			//表格全选事件
			selectAll(rows) {
				var isAllSelect = rows.length > 0
				if (isAllSelect) {
					rows.forEach(row => {
						var isHas = this.defaultValue.find(item => item[this.defaultProps.value] == row[this
							.defaultProps.value])
						if (!isHas) {
							this.defaultValue.push(row)
						}
					})
				} else {
					this.tableData.forEach(row => {
						var isHas = this.defaultValue.find(item => item[this.defaultProps.value] == row[this
							.defaultProps.value])
						if (isHas) {
							this.defaultValue.splice(this.defaultValue.findIndex(item => item[this.defaultProps
								.value] == row[this.defaultProps.value]), 1)
						}
					})
				}
				this.autoCurrentLabel()
				this.$emit('update:modelValue', this.defaultValue);
				this.$emit('change', this.defaultValue);
			},
			click(row) {
				if (this.multiple) {
					//处理多选点击行
				} else {
					this.defaultValue = row
					this.$refs.select.blur()
					this.autoCurrentLabel()
					this.$emit('update:modelValue', this.defaultValue);
					this.$emit('change', this.defaultValue);
				}
			},
			//tags删除后回调
			removeTag(tag) {

				if (this.panelModel?.length > 0) {
					// 用 findIndex 获取元素索引
					const index = this.panelModel.findIndex(item => item === tag[this.defaultProps.value]);

					if (index !== -1) {
						// 用 splice 删除元素
						this.panelModel.splice(index, 1);

						this.$refs.cascaderPanelRef.calculateCheckedValue()
					}
				}

				if (this.defaultValue?.length > 0) {

					// 用 findIndex 获取元素索引
					const index = this.defaultValue.findIndex(item => item[this.defaultProps.value] === tag[this
						.defaultProps.value]);

					if (index !== -1) {
						// 用 splice 删除元素
						this.defaultValue.splice(index, 1);

					}

				}

				this.$emit('update:modelValue', this.defaultValue);
			},
			//清空后的回调
			clear() {
				this.$refs.cascaderPanelRef?.clearCheckedNodes()
				this.$emit('update:modelValue', this.defaultValue);
			},
			// 关键值查询表格数据行
			findRowByKey(value) {
				return this.tableData.find(item => item[this.defaultProps.value] === value)
			},
			filterMethod(keyword) {
				if (!keyword) {
					this.hideSuggestionPanel()
					return false;
				}
				//this.keyword = keyword;
				this.suggestions = this.$refs.cascaderPanelRef.getFlattedNodes(true)
					.filter((node) => {
						if (node.isDisabled) return false
						node.calcText(true, "/")
						return ~node.text.indexOf(keyword)
					})
				this.filtering = true;
			},
			// 触发select隐藏
			blur() {
				this.$refs.select.blur();
			},
			// 触发select显示
			focus() {
				this.$refs.select.focus();
			},
			hideSuggestionPanel() {
				this.suggestions = [];
				this.filtering = false;
			},
			handleSuggestionClick(node) {
				const {
					checked
				} = node
				this.$refs.cascaderPanelRef.handleCheckChange(node, !checked, false)
			}
		}
	}
</script>


<style>
	.ta-cascader-popper .el-select-dropdown__empty {
		padding: 0px !important;
	}

	.ta-cascader-popper.el-select-dropdown {
		min-width: auto !important;
	}
</style>

<style scoped>
	.sc-table-select__table {
		padding: 0px;
	}
</style>
